﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

//Si vous déclarez dans une classe dérivée une méthode ayant la même signature qu'une méthode statique de la classe ancêtre,
//la nouvelle méthode remplace simplement (on dit aussi masque) la méthode héritée dans la classe dérivée, utilisez le mot clef new pour améliorer la lisibilité.
//(mais à clarifier qu'il faut que l'instance de la classe fille doit être rangée dans la variable de classe fille (pas celle de classe mère).

//Si l'instance de la classe fille est rangée dans dans la variable de type classe mère,
//la méthode par défaut de la classe mère sera appelée. Et c'est simplement ca qui distingue avec override.
//Le terme "Masquage" joue le role ici. Il masque la méthode d'origine. A recommender utiliser le mot new.

//Autrement dit: Si l'instance de la classe fille est rangée dans la variable de type classe fille. 
//C'est pour appeler la nouvelle méthode de classe fille (quelque soit override ou new dans la classe fille).


//A distinguer avec la méthode statique de classe (impossible de redéfinir). C'est une méthode partageable par tous les instance d'objet de la meme classe.
//Tantdis que méthode à la liaison statique (virtual ou pas, puis new ou pas) concernant la relation entre classe mère et la "rédefinition" dans la classe fille . 

//Une méthode statique ne change pas lorsqu'elle est transmise en héritage à une autre classe.
//Si vous déclarez une classe qui inclut une méthode statique, puis en dérivez une nouvelle classe, 
//la classe dérivée partage exactement la même méthode située à la même adresse. 
//Cela signifie qu'il est impossible de redéfinir les méthodes statiques; une méthode statique fait toujours 
//exactement la même chose, quelque soit la classe dans laquelle elle est appelée????? Bizzare, le test ne donne pas ce genre de résultat:


namespace MethodeLiaisonPrecoce
{
      class Vehicule
    {
        protected int nbr_passager = 0;
        public Vehicule()
        {
            Console.WriteLine("(constructeur Vehicule) Nombre de passagers = " + nbr_passager);
        }
        public void Passager(int nb) // méthode à liaison statique
        {
            nbr_passager = nb;
            Console.WriteLine("(Vehicule) Nombre de passagers =  " + nbr_passager);
        }
          public static void MethodeStatic()
          {
              Console.WriteLine("Test MethodeStatic  ");
          }
    }

    class Terrestre : Vehicule
    {
        public static void MethodeStatic()
        {
            Console.WriteLine("Test MethodeStatic si c'est redifinissable  ");
        }
        public new  void Passager(int nb) // méthode à liaison statique masquant celle de classe Vehicule
        {
            nbr_passager = nb + 1;
            Console.WriteLine("(Terrestre ) Nombre de passagers = .. " + nbr_passager); // cette méthode ne passe pas
        }
    }

    class Voiture : Terrestre
    {
        public new void Passager(int nb) // méthode à liaison statique masquant celle de classe Terrestre 
        {
            nbr_passager = nb + 2;
            Console.WriteLine("(Voiture ) Nombre de passagers = .. " + nbr_passager); // cette méthode ne passe pas
        }
    }

    class Exercice
    {
        public static void Main(string[] args) // méthode principale de lancement de l'exécution
        {
            Vehicule mercedes; // l'instance de la classe fille est rangée dans dans la variable de type classe mère. 
            //Donc tjours la méthode d'origine (de classe mère) sera appelée:

            
            mercedes = new Vehicule();
            mercedes.Passager(3);// méthode Passager de la classe Vehicule  qui est utilisée

            mercedes = new Terrestre();
            mercedes.Passager(3);// méthode Passager de la classe Vehicule  qui est utilisée
                        
            mercedes = new Voiture();
            mercedes.Passager(3);// méthode Passager de la classe Vehicule  qui est utilisée

            Voiture v; //l'instance de la classe fille doit être rangée dans la variable de classe fille. Le terme "Masquage" joue le role ici.
            v = new Voiture();
            v.Passager(3);

            Vehicule.MethodeStatic();
            //Terrestre t = new Terrestre();
           // t.MethodeStatic();
            Terrestre.MethodeStatic();

            Console.ReadLine();
        }
    }
}
